День 1 Летней школы Julia 2025
Переменные
Переменная в Julia — это имя, связанное со значением (или привязанное к нему). Ее целесообразно применять, когда вы хотите сохранить значение (полученное, например, после математических вычислений) для последующего использования.
x = 2 * 3
Система именований переменных в Julia очень гибкая. А имена переменных зависят от регистра.
Так в Julia допустимы именования на русском языке.
переменная = 2 + 3
Более того, имена переменных могут состоять из Unicode-символов. Например символ яблока может быть связан со строкой "Яблоко".
Далее в нашем коде при использовании этого символа мы будем получать значение объекта, на который ссылаемся наша переменная - то есть на строку яблоко
🍎 = "Яблоко"
Но всё же лучше придерживаться общепринятых обозначений, таких, как дельта_x.
Здесь 1e-4 означает 1*10-4
И символ яблока и символ дельта х не используются в базовом модуле языка. Однако есть специальные символы, такие как пи, которые имеют определённое значение.
Δx = 1e-4
Также стоит отметить, что для повышения читабельности кода в Julia имеется возможность записывать умножение переменной на число, записав численные литералы перед переменной.
x = 2π
но из-за этого переменные не могут начинаться с числа
x = 3
2x = 4
В случае же числа pi мы имеем не литерал, а символ, связанный с числом пи. Поэтому для умножения на него необходимо ставить знак умножения.
r = 3;
πr^2
Затронем тему систем типизации в языках.
Системы типов традиционно делятся на две довольно сильно отличающиеся друг от друга категории: статические, в которых тип каждого выражения определяется перед выполнением программы, и динамические, в которых о типах ничего неизвестно до выполнения, пока не станут доступными фактические значения. В языках со статической типизацией объектный подход допускает некоторую гибкость: при написании кода необязательно точно знать типы значений на момент компиляции. Явление, когда один и тот же код может оперировать разными типами, называется полиморфизмом. В классических языках с динамической типизацией весь код является полиморфическим: типы значений ограничиваются только при явной проверке типов или в том случае, если операции с объектами не поддерживаются во время выполнения.
Система типов в Julia является динамической, но обладает некоторыми преимуществами статических систем: вы можете указывать, что тот или иной объект имеет определенный тип. Это не только помогает создавать более эффективный код, но и, что еще более важно, позволяет глубоко интегрировать в язык диспетчеризацию методов на основе типов аргументов. Диспетчеризация методов подробно рассматривается в главе Методы, но корни она берет в описываемой здесь системе типов.
Другими словами, в Julia допускается смена типа объекта, на который ссылается переменная. До этого х ссылался на число, а теперь переменная с тем же именем означает строку.
x = "Hello," * "String!"
Ещё одной особенностью Julia, отличающей её, например от C, является то, что мы не можем создать переменную без значения.
int x; // Так в Julia не получится
И если в Си int x; - допустимое выражение для объявления переменной, то в Julia это будет ошибкой.
Переменные в Julia скорее похожи на ссылки в C++:
Мы можем объявить неинициализировынный указатель, но не ссылку
int x = 1;
// int& r; // ОШИБКА
int& r = x;
Чтобы узнать тип объекта, на который ссылается переменная - воспользуемся функцией typeof
typeof(x)
Отметим также, что объектами в Julia могут выступать как объекты в привычном понимании, так и типы, функции и даже модули.
Практически всё в Julia является объектами, поэтому переменная может быть связана с
- "объектом"
- типом
- функцией
- модулем
целое = Int
a = целое(2*3)
Мы рассматривали с вами символ числа пи, который указывал на иррациональное число. Но также можно воспользоваться символом квадратного корня, который в свою очередь ссылает на функцию sqrt.
Т.е. мы сами можем задавать переменные, которые будут связаны с функцией, если мы считаем, что это повысит читабельность кода.
И в некоторых случаях мы можем даже вставлять эти символы в центр выражения, между двумя аргументами.
sqrt(9)
√25
∑ = sum
∑([1,2,3])
Используя символы из списка можно делать инфиксные операторы
⊞(x, y) = 100(x + y)
2 ⊞ 3
Мы узнали как связывать переменные с числами и функциями. Но как же нам разорвать эту связь или удалить переменную?
Как мы с вами узнали, что переменные в Julia это ссылки на объекты. И мы можем начать ссылаться переменной на другой объект. Но оставить переменную и сделать так чтобы она ни на что не указывала мы не можем. Зато мы можем сделать по-другому: указывать на ничто))))
nothing это не число и даже не ноль или нулевой указатель. Поэтому присваивание переменной значения nothing позволит вам освободить память, если наша переменная указывала на большой массив и больше он нам не нужен. Тогда сборщик мусора удалит этот вектор.
В отличие от MATLAB, переменную нельзя очистить.
Но ей можно присвоить значение nothing
x = nothing
print(x)
x + 1
Мы узнали как задать переменную и как её очистить.
Но для написания эффективного кода следует указывать тип глобальных переменных. Это позволяет компилятору создавать более эффективные программы.
Чтобы задать переменной тип, необходимо после её имени поставить двойное двоеточие.
Так, для переменной, обозначающей количество секунд в минуте - логично выбрать тип целочисленное число, а не строку, например.
Но, забегая вперёд, скажу, что 60. обозначает вещественное, а не целочисленое число.
И, соответственно,для целочисленной переменной смена типа объекта с целочисленного на вещественный приводит к ошибке.
Но что делать, если мы хотим зафиксировать не только тип глобальной переменной, но и её значение?
Для этого можно применить слово const.
В этом случае мы можем не прописывать тип через двойное двоеточие, а просто использовать присваивание. Тогда Julia сама определит и зафиксирует тип переменной.
При смене значения переменной, будет выведено предупреждение о том, что произошла смена значения.
В случае же смены типа, что для константных, что для типизированных переменных, выведется не предупреждение, а вызовется ошибка.
sec_per_minute::Int = 60.
sec_per_minute
const gₑ = 9.81
gₑ = 9.
gₑ = 9